package org.convallaria.infrastruct.rg.config;

import org.convallaria.infrastruct.rg.feign.FeignConfig;
import org.convallaria.infrastruct.rg.health.ServiceHealthChecker;
import org.convallaria.infrastruct.rg.loadbalancer.CustomLoadBalancer;
import org.convallaria.infrastruct.rg.monitor.RegistryMetrics;
import org.convallaria.infrastruct.rg.service.ConfigManagementService;
import org.convallaria.infrastruct.rg.service.NoOpConfigManagementService;
import org.convallaria.infrastruct.rg.service.ServiceDiscoveryManager;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.web.client.RestTemplate;

/**
 * 注册发现自动配置类
 * 使用原生 Spring Cloud Nacos 配置，简化自定义配置
 * 
 * @author gjh
 * @since 2025-01-27
 */
@Configuration
@EnableConfigurationProperties(RegistryProperties.class)
@EnableRetry
@ConditionalOnClass(name = "com.alibaba.cloud.nacos.NacosDiscoveryProperties")
@ConditionalOnProperty(prefix = "convallaria.registry", name = "enabled", havingValue = "true", matchIfMissing = true)
@Import({FeignConfig.class})
public class RegistryAutoConfiguration {
    
    /**
     * 配置RestTemplate
     * 
     * @return RestTemplate
     */
    @Bean
    @ConditionalOnMissingBean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    
    /**
     * 配置监控指标
     * 
     * @param meterRegistry MeterRegistry
     * @return RegistryMetrics
     */
    @Bean
    @ConditionalOnMissingBean
    public RegistryMetrics registryMetrics(io.micrometer.core.instrument.MeterRegistry meterRegistry) {
        return new RegistryMetrics(meterRegistry);
    }
    
    /**
     * 配置服务发现管理器
     * 使用原生 NacosDiscoveryProperties
     * 
     * @return ServiceDiscoveryManager
     */
    @Bean
    @ConditionalOnMissingBean
    public ServiceDiscoveryManager serviceDiscoveryManager(
            com.alibaba.cloud.nacos.discovery.NacosServiceDiscovery nacosServiceDiscovery,
            RegistryProperties registryProperties,
            RegistryMetrics registryMetrics) {
        return new ServiceDiscoveryManager(nacosServiceDiscovery, registryProperties, registryMetrics);
    }
    
    /**
     * 配置自定义负载均衡器
     * 
     * @param loadBalancerClient LoadBalancerClient
     * @return CustomLoadBalancer
     */
    @Bean
    @ConditionalOnMissingBean
    public CustomLoadBalancer customLoadBalancer(LoadBalancerClient loadBalancerClient) {
        return new CustomLoadBalancer(loadBalancerClient);
    }
    
    /**
     * 配置服务健康检查器
     * 使用原生 NacosDiscoveryProperties
     * 
     * @param restTemplate RestTemplate
     * @param registryProperties RegistryProperties
     * @param registryMetrics RegistryMetrics
     * @return ServiceHealthChecker
     */
    @Bean
    @ConditionalOnMissingBean
    public ServiceHealthChecker serviceHealthChecker(
            RestTemplate restTemplate,
            RegistryProperties registryProperties,
            RegistryMetrics registryMetrics) {
        return new ServiceHealthChecker(restTemplate, registryProperties, registryMetrics);
    }
    
    /**
     * 配置管理服务
     * 只有在Nacos配置中心可用时才创建
     * 
     * @param configService ConfigService
     * @return ConfigManagementService
     */
    @Bean
    @ConditionalOnMissingBean(ConfigManagementService.class)
    @ConditionalOnClass(name = "com.alibaba.nacos.api.config.ConfigService")
    @ConditionalOnBean(com.alibaba.nacos.api.config.ConfigService.class)
    public ConfigManagementService configManagementService(
            com.alibaba.nacos.api.config.ConfigService configService) {
        return new ConfigManagementService(configService);
    }
    
    /**
     * 备用配置管理服务
     * 当Nacos配置中心不可用时提供基本功能
     * 
     * @return NoOpConfigManagementService
     */
    @Bean
    @ConditionalOnMissingBean(ConfigManagementService.class)
    public NoOpConfigManagementService noOpConfigManagementService() {
        return new NoOpConfigManagementService();
    }
}
